package com.usky.pss.refundticket.service.support;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.usky.pss.ibe.entity.ticket.TicketSegment;
import com.usky.pss.order.entity.OrderDO;
import com.usky.pss.order.entity.OrderProductDO;
import com.usky.pss.order.entity.PaxDO;
import com.usky.pss.order.entity.SegmentDO;
import com.usky.pss.order.entity.SubSegmentDO;
import com.usky.pss.order.service.OrderService;
import com.usky.pss.refundticket.entity.bo.RefundSegmentBO;
import com.usky.pss.refundticket.entity.query.CreateRefundTicketParamInfo;
import com.usky.pss.refundticket.entity.query.RefundTicketProductParamInfo;
import com.usky.pss.refundticket.exception.RefundRuleException;
import com.usky.pss.refundticket.service.RefundRuleNewService;
import com.usky.pss.refundticket.work.TicketStatusTask;
import com.usky.pss.refundticket.work.TicketStatusWorker;
import com.usky.pss.refundticket.work.WorkerMaster;

/**
 * Created by Jeremy on 2016/11/9.
 */
@Service
public class RefundRuleNewServiceImpl implements RefundRuleNewService {

    @Autowired
    private OrderService orderService;

    //退票规则的总校验
    public void refundRuleValidity(CreateRefundTicketParamInfo refundTicketParamInfo) throws RefundRuleException{
        //退票时间有效期的校验
        this.checkRefundDateValidity(refundTicketParamInfo);
        //客票有效期的校验
        this.checkTicketStatus(refundTicketParamInfo);
    }
    //
    public void checkRefundDateValidity(CreateRefundTicketParamInfo refundTicketParamInfo) throws RefundRuleException{
        String orderNo = refundTicketParamInfo.getOrderNo();
        OrderDO orderDO = orderService.getOrderDOByOrderNo(orderNo);
        Set<OrderProductDO> orderProductDOSet = orderDO.getOrderProductDOSet();
        List<RefundTicketProductParamInfo> productParamInfoList = refundTicketParamInfo.getProductParamInfoList();
        for (RefundTicketProductParamInfo refundTicketProductParamInfo : productParamInfoList){
//            String paxId = refundTicketProductParamInfo.getPaxId();
            String opid = refundTicketProductParamInfo.getOrderProductId();
            String subid = refundTicketProductParamInfo.getSubSegId();
            for (OrderProductDO orderProductDO : orderProductDOSet){
                if (opid==null?false:opid.equals(String.valueOf(orderProductDO.getId()))){
                    if (subid==null){
                        SegmentDO segmentDO = orderProductDO.getSegment();
                        boolean refundDateValidity = this.checkRefundDate(segmentDO.getTakeOffTime(),new Date());
                        if (!refundDateValidity) throw new RefundRuleException(RefundRuleException.REFUND_DATE_VALIDITY_FALSE);
                    }else {
                        SegmentDO segmentDO = orderProductDO.getSegment();
                        Set<SubSegmentDO> subSegmentDOSet = segmentDO.getSubSegmentDOSet();
                        List<SubSegmentDO> subSegmentDOList = new ArrayList<>(subSegmentDOSet);
                        Collections.sort(subSegmentDOList, new Comparator<SubSegmentDO>() {
                            @Override
                            public int compare(SubSegmentDO o1, SubSegmentDO o2) {
                                if (o1.getTakeOffTime().before(o2.getTakeOffTime())) return -1;
                                return 1;
                            }
                        });
                        //矢量航程按第一段的起飞日期来算有效期
                        SubSegmentDO subSegmentDOFirst = subSegmentDOList.get(0);
                        boolean refundDateValidity = this.checkRefundDate(subSegmentDOFirst.getTakeOffTime(),new Date());
                        if (!refundDateValidity) throw new RefundRuleException(RefundRuleException.REFUND_DATE_VALIDITY_FALSE);
                    }
                }
            }
        }

    }

    //退票有效期的校验：退票有效期均以航班起飞日期算，一年。（多段时，已第一段的航班起飞日期算）
    public boolean checkRefundDate(Date depDate, Date refundDate){
        GregorianCalendar gregorianCalendar = new GregorianCalendar();
        gregorianCalendar.setTime(depDate);
        gregorianCalendar.add(1,1);//一年有效期
        if (gregorianCalendar.getTime().before(refundDate)) return false;
        return true;
    }

    //客票状态的校验：未使用的客票才能退票
    public void checkTicketStatus(CreateRefundTicketParamInfo refundTicketParamInfo) throws RefundRuleException{
        List<RefundSegmentBO> refundSegmentBOs = this.getRefundSegmentBOList(refundTicketParamInfo);
        Set<String> ticketNoSet = new HashSet<>();
        for (RefundSegmentBO refundSegmentBO : refundSegmentBOs){
            ticketNoSet.add(refundSegmentBO.getTicketNo());
        }
        List<String> ticketNos = new ArrayList<>(ticketNoSet);
        ConcurrentHashMap<String,TicketStatusTask> ticketStatusResult = this.getTicketStatus(ticketNos);

        if (!ticketStatusResult.isEmpty() && ticketStatusResult.size()>0){

            for (RefundSegmentBO refundSegmentBO : refundSegmentBOs){
                String ticketNo = refundSegmentBO.getTicketNo();
                TicketStatusTask task = ticketStatusResult.get(ticketNo);
                List<TicketSegment> segmentStatuses = task.getTaskResult();
                if(segmentStatuses!=null){
                    for (TicketSegment segmentStatus : segmentStatuses){
                        if (refundSegmentBO.getDepAirportCode().equals(segmentStatus.getDepAirportCode()) &&
                                refundSegmentBO.getArrAirportCode().equals(segmentStatus.getArrAirportCode())){
                            if (!"OPEN FOR USE".equals(segmentStatus.getStatus())){
                                throw new RefundRuleException(RefundRuleException.NON_REFUND);
                            }
                        }
                    }
                }

            }
        }




    }

    public List<RefundSegmentBO> getRefundSegmentBOList(CreateRefundTicketParamInfo refundTicketParamInfo){
        List<RefundSegmentBO> refundSegmentBOs = new ArrayList<>();
        List<RefundTicketProductParamInfo> productParamInfoList = refundTicketParamInfo.getProductParamInfoList();
        String orderNo = refundTicketParamInfo.getOrderNo();
        OrderDO orderDO = orderService.getOrderDOByOrderNo(orderNo);
        Set<OrderProductDO> orderProductDOSet = orderDO.getOrderProductDOSet();
        for (RefundTicketProductParamInfo refundTicketProductParamInfo : productParamInfoList){
            String paxid = refundTicketProductParamInfo.getPaxId();
            String opid = refundTicketProductParamInfo.getOrderProductId();
            String subid = refundTicketProductParamInfo.getSubSegId();
            for (OrderProductDO orderProductDO : orderProductDOSet){
                if (opid==null?false:opid.equals(String.valueOf(orderProductDO.getId()))){
                    PaxDO paxDO = orderProductDO.getPax();
                    if (paxid==null?false:paxid.equals(String.valueOf(paxDO.getId()))){
                        if (subid==null){
                            SegmentDO segmentDO = orderProductDO.getSegment();
                            RefundSegmentBO refundSegmentBO = new RefundSegmentBO();
                            refundSegmentBO.setArrAirportCode(segmentDO.getArrivalPort());
                            refundSegmentBO.setDepAirportCode(segmentDO.getDeparturePort());
                            refundSegmentBO.setTicketNo(segmentDO.getTktNo());
                            refundSegmentBOs.add(refundSegmentBO);
                        }else {
                            SegmentDO segmentDO = orderProductDO.getSegment();
                            Set<SubSegmentDO> subSegmentDOSet = segmentDO.getSubSegmentDOSet();
                            for (SubSegmentDO subSegmentDO : subSegmentDOSet){
                                if (subid.equals(String.valueOf(subSegmentDO.getId()))){
                                    RefundSegmentBO refundSegmentBO = new RefundSegmentBO();
                                    refundSegmentBO.setArrAirportCode(subSegmentDO.getArrivalPort());
                                    refundSegmentBO.setDepAirportCode(subSegmentDO.getDeparturePort());
                                    refundSegmentBO.setTicketNo(subSegmentDO.getTktNo());
                                    refundSegmentBOs.add(refundSegmentBO);
                                }
                            }
                        }
                    }
                }
            }
        }
        return refundSegmentBOs;
    }

    //客票状态的查询
    public ConcurrentHashMap<String,TicketStatusTask> getTicketStatus(List<String> ticketNos){
        ConcurrentHashMap<String,TicketStatusTask> result = null;
        TicketStatusWorker worker = new TicketStatusWorker();
        WorkerMaster master = new WorkerMaster(worker,ticketNos.size());
        if (!ticketNos.isEmpty() && ticketNos.size()>0){

            for (String ticketNo: ticketNos){
                if (ticketNo!=null){
                    TicketStatusTask task = new TicketStatusTask();
                    task.setTicketNo(ticketNo);
                    master.submit(task);
                }
            }
            master.execute();
            while (true){
                if (master.isComplete()){
                    result = master.getWorkResult();
                    break;
                }
            }
        }

        return result;
    }



}
